﻿// Copyright (c) Microsoft Corporation
// All rights reserved

namespace Microsoft.Windows.Controls.Specialized.TextModel
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Text;

    /// <summary>
    /// Describes a possibly empty span of text with respect to some (unspecified) text buffer.
    /// </summary>
    public class TextSpan : Span, IEquatable<TextSpan>
    {
        ITextBuffer _buffer;
        TextPoint _startPoint, _endPoint;

        public TextSpan(ITextBuffer buffer, int start, int length)
            : this(buffer, buffer.Version, start, length)
        { 
        }

        public TextSpan(ITextBuffer buffer, ITextVersion version, Span span)
            : this(buffer, version, span.Start, span.Length)
        {
        }
        
        public TextSpan(ITextBuffer buffer, ITextVersion version, int start, int length)
            : base()
        {
            if (start + length > buffer.GetLengthOfVersion(version))
                throw new ArgumentOutOfRangeException("length");

            _buffer = buffer;
            _startPoint = new TextPoint(buffer, version, start, TrackingMode.Negative);
            _endPoint = new TextPoint(buffer, version, start + length, TrackingMode.Positive);
        }

        public override int Start
        {
            get
            {
                return _startPoint;
            }
        }

        public override int End
        {
            get
            {
                return _endPoint;
            }
        }

        public override int Length
        {
            get
            {
                return End - Start;
            }
        }

        /// <summary>
        /// Gets the Text Buffer backing this text span.
        /// </summary>
        public ITextBuffer TextBuffer
        {
            get
            {
                return _buffer;
            }
        }

        public string GetText()
        {
            return _buffer.GetText(Start, Length);
        }

        public bool Equals(TextSpan other) {
            if (other != null) {
                return _buffer == other._buffer &&
                    _startPoint == other._startPoint &&
                    _endPoint == other._endPoint;
            }
            return false;
        }
    }
}
